﻿using System;
using System.Collections.Generic;
using ICeFramework.Common.DataLayer;

namespace ICeFramework.Business.DataLayer
{
    public class EntityRowErrorCollection : ICollection<EntityRowError>
    {
        private List<EntityRowError> _list = new List<EntityRowError>();

        #region public void Add(EntityColumn column, string errorCode, string errorMessage)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="column"></param>
        /// <param name="errorCode"></param>
        /// <param name="errorMessage"></param>
        public void Add(EntityColumn column, string errorCode, string errorMessage)
        {
            if (!ContainsMessage(errorMessage) || !ContainsColumn(column))
            {
                EntityRowError item;
                if ((object)column != null)
                {
                    string message = string.Format("{0}: {1} (Error Code: {2})", column.DisplayName, errorMessage, errorCode);
                    item = new EntityRowError(column, errorCode, message);
                }
                else
                {
                    string message = string.Format("{0} (Error Code: {1})", errorMessage, errorCode);
                    item = new EntityRowError(errorCode, message);
                }
                _list.Add(item);
            }
        }
        #endregion

        #region public void Add(string errorCode, string errorMessage)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="errorCode"></param>
        /// <param name="errorMessage"></param>
        public void Add(string errorCode, string errorMessage)
        {
            Add(null, errorCode, errorMessage);
        }
        #endregion

        #region private bool ContainsCode(string errorCode)
        /// <summary>
        /// Returns a value indicating whether the specified <see cref="String"/>
        ///  is contained in the <see cref="Business.Common.EntityRowErrorCollection"/>.
        /// </summary>
        /// <param name="errorCode">The <see cref="String"/> to locate in the 
        /// <see cref="Business.Common.EntityRowErrorCollection"/>.</param>
        /// <returns><b>true</b> if the <i>String</i> parameter is a member 
        /// of the <see cref="Business.Common.EntityRowErrorCollection"/>; otherwise, <b>false</b>.</returns>
        private bool ContainsCode(string errorCode)
        {
            if (string.IsNullOrEmpty(errorCode))
            {
                return true;
            }

            foreach (EntityRowError item in _list)
            {
                if (item.ErrorCode == errorCode)
                {
                    return true;
                }
            }
            return false;
        }
        #endregion

        #region private bool ContainsMessage(string errorMessage)
        /// <summary>
        /// Returns a value indicating whether the specified <see cref="String"/>
        ///  is contained in the <see cref="Business.Common.EntityRowErrorCollection"/>.
        /// </summary>
        /// <param name="errorMessage">The <see cref="String"/> to locate in the 
        /// <see cref="Business.Common.EntityRowErrorCollection"/>.</param>
        /// <returns><b>true</b> if the <i>String</i> parameter is a member 
        /// of the <see cref="Business.Common.EntityRowErrorCollection"/>; otherwise, <b>false</b>.</returns>
        private bool ContainsMessage(string errorMessage)
        {
            if (string.IsNullOrEmpty(errorMessage))
            {
                return true;
            }
            foreach (EntityRowError item in _list)
            {
                if (item.ErrorMessage == errorMessage)
                {
                    return true;
                }
            }
            return false;
        }
        #endregion

        #region private bool ContainsColumn(EntityColumn column)
        /// <summary>
        /// Returns a value indicating whether the specified <see cref="EntityColumn"/>
        ///  is contained in the <see cref="Business.Common.EntityRowErrorCollection"/>.
        /// </summary>
        /// <param name="column">The <see cref="EntityColumn"/> to locate in the 
        /// <see cref="Business.Common.EntityRowErrorCollection"/>.</param>
        /// <returns><b>true</b> if the <i>EntityColumn</i> parameter is a member 
        /// of the <see cref="Business.Common.EntityRowErrorCollection"/>; otherwise, <b>false</b>.</returns>
        private bool ContainsColumn(EntityColumn column)
        {
            if ((object)column == null)
            {
                return true;
            }
            foreach (EntityRowError item in _list)
            {
                if ((object)item.Column != null && item.Column.Name == column.Name)
                {
                    return true;
                }
            }
            return false;
        }
        #endregion

        #region ICollection<RowValidationError> Members

        public void Add(EntityRowError item)
        {
            _list.Add(item);
        }

        public void Clear()
        {
            _list.Clear();
        }

        public bool Contains(EntityRowError item)
        {
            return _list.Contains(item);
        }

        public bool Contains(string errorMessage)
        {
            foreach (EntityRowError item in _list)
            {
                if (item.ErrorMessage == errorMessage)
                {
                    return true;
                }
            }
            return false;
        }

        public bool Contains(string errorCode, string errorMessage)
        {
            foreach (EntityRowError item in _list)
            {
                if (item.ErrorMessage == errorMessage && item.ErrorCode == errorCode)
                {
                    return true;
                }
            }
            return false;
        }

        public void CopyTo(EntityRowError[] array, int arrayIndex)
        {
            _list.CopyTo(array, arrayIndex);
        }

        public int Count
        {
            get { return _list.Count; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        public bool Remove(EntityRowError item)
        {
            return _list.Remove(item);
        }

        #endregion
        
        #region IEnumerable<RowValidationError> Members

        public IEnumerator<EntityRowError> GetEnumerator()
        {
            return _list.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _list.GetEnumerator();
        }

        #endregion
    }
}
